//
//  FMaskView.m
//  Foundation
//
//  Created by 三井 on 2019/10/25.
//

#import "FMaskView.h"
#import "UIView+FView.h"

static NSString * const kShapeLayerPathAnimationKey = @"kShapeLayerPathAnimationKey";
@interface FMaskView ()

@property (nonatomic, strong) CAGradientLayer *gradientLayer;
@property (nonatomic, strong) CAShapeLayer *shapeLayer;

@end

@implementation FMaskView

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self prepareSubviews];
    }
    return self;
}

- (void)prepareSubviews {
    self.backgroundColor = [UIColor whiteColor];
}

- (void)setFrame:(CGRect)frame {
    self.shapeLayer.frame = CGRectMake(0, 0, frame.size.width, frame.size.height);
    [super setFrame:frame];
}

- (void)maskOff {
    self.maskFor.maskView = nil;
}

#pragma mark - Shape
- (void)shapeAll:(BOOL)animate {
    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:CGFLOAT_MIN];
    [self shapePath:path.CGPath duration:0.35 animated:animate];
}

- (void)shapeCircel:(CGFloat)radius {
    [self shapeCircle:radius center:CGPointMake(0.5, 0.5)];
}

- (void)shapeCircle:(CGFloat)radius center:(CGPoint)anchor {
    [self shapeCircle:radius center:anchor animated:NO];
}

- (void)shapeCircle:(CGFloat)radius center:(CGPoint)anchor animated:(BOOL)animate {
    CGFloat x = anchor.x * self.jk_width;
    CGFloat y = anchor.y * self.jk_height;
    CGRect rect = CGRectMake(x - radius, y - radius, 2 * radius, 2 * radius);
    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius];
    
    [self shapePath:path.CGPath duration:0.35 animated:animate];
}

- (void)shapeCorner:(UIRectCorner)corner radius:(CGFloat)radius {
    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:corner cornerRadii:CGSizeMake(radius, radius)];
    [self shapePath:path.CGPath duration:0 animated:NO];
}

- (void)shapePath:(CGPathRef)path duration:(CGFloat)duration animated:(BOOL)animate {
    self.backgroundColor = [UIColor clearColor];
    
    self.shapeLayer.masksToBounds = YES;
    
    if (!animate) {
        self.shapeLayer.path = path;
    } else {
        CABasicAnimation *basiceAnimation = [self animateOfPathFor:self.shapeLayer];
        basiceAnimation.duration = duration;
        basiceAnimation.fromValue = (__bridge id)self.shapeLayer.path;
        basiceAnimation.toValue = (__bridge id)path;
        self.shapeLayer.path = path;
        [self.shapeLayer addAnimation:basiceAnimation forKey:kShapeLayerPathAnimationKey];
    }
}

#pragma mark - Gradient
- (void)gradientAlpha:(NSArray<NSNumber *> *)locations direction:(CGVector)direction {
    CGPoint start = CGPointZero;
    CGPoint end = CGPointMake(direction.dx, direction.dy);
    
    if (end.x < 0) {
        start.x += -end.x;
        end.x = 0;
    }
    if (end.y < 0) {
        start.y += -end.y;
        end.y = 0;
    }
    
    [self gradientColor:@[[UIColor clearColor], [UIColor whiteColor]] locations:locations from:start to:end];
}

- (void)gradientColor:(NSArray<UIColor *> *)colors locations:(NSArray<NSNumber *> *)locations from:(CGPoint)start to:(CGPoint)end {
    self.backgroundColor = [UIColor clearColor];
    
    self.gradientLayer.colors = [colors jk_map:^id(id object) {
        return (__bridge id)[(UIColor *)object CGColor];
    }];
    self.gradientLayer.locations = locations;
    self.gradientLayer.startPoint = start;
    self.gradientLayer.endPoint = end;
    [self.gradientLayer setNeedsLayout];
}

- (CAGradientLayer *)gradientLayer {
    if (!_gradientLayer) {
        _gradientLayer = [CAGradientLayer layer];
        _gradientLayer.frame = self.bounds;
        [self.layer addSublayer:_gradientLayer];
    }
    return _gradientLayer;
}

- (CAShapeLayer *)shapeLayer {
    if (!_shapeLayer) {
        _shapeLayer = [CAShapeLayer layer];
        _shapeLayer.frame = self.bounds;
        _shapeLayer.path = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:CGFLOAT_MIN].CGPath;
        [self.layer addSublayer:_shapeLayer];
    }
    return _shapeLayer;
}

- (CABasicAnimation *)animateOfPathFor:(CAShapeLayer *)layer {
    // 如果不移除，每次取旧值会导致出现，readonly object immutable crash
    [layer removeAnimationForKey:kShapeLayerPathAnimationKey];
    
    CABasicAnimation *animation = animation = [CABasicAnimation animationWithKeyPath:@"path"];
    return animation;
}

@end
